From d3ee9f833a672e1efd7343b21541500b0b115988 Mon Sep 17 00:00:00 2001 From: Richard Hult Date: Tue, 8 Aug 2006 20:53:09 +0000 Subject: [PATCH] Just expose the minimal region instead of the whole rect. 2006-08-08 Richard Hult * gdk/quartz/GdkQuartzView.c: Just expose the minimal region instead of the whole rect. * gdk/quartz/gdkwindow-quartz.c: (gdk_window_quartz_process_all_updates), (gdk_window_update_idle), (gdk_window_impl_quartz_invalidate_maybe_recurse), (gdk_window_impl_quartz_process_updates), (_gdk_windowing_window_destroy): Rework the expose handling so that it works like the X11 backend, using an idle with the right priority instead of relying on quartz to do it. (gdk_window_set_type_hint): Use tornoff instead of submenu as the documentation (and Mitch) suggests. --- ChangeLog | 15 +++++ ChangeLog.pre-2-10 | 15 +++++ gdk/quartz/GdkQuartzView.c | 33 ++++++++--- gdk/quartz/gdkwindow-quartz.c | 104 ++++++++++++++++++++++++++++------ 4 files changed, 143 insertions(+), 24 deletions(-) diff --git a/ChangeLog b/ChangeLog index df068f943b..c994b205c4 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,18 @@ +2006-08-08 Richard Hult + + * gdk/quartz/GdkQuartzView.c: Just expose the minimal region + instead of the whole rect. + + * gdk/quartz/gdkwindow-quartz.c: + (gdk_window_quartz_process_all_updates), (gdk_window_update_idle), + (gdk_window_impl_quartz_invalidate_maybe_recurse), + (gdk_window_impl_quartz_process_updates), + (_gdk_windowing_window_destroy): Rework the expose handling so that + it works like the X11 backend, using an idle with the right + priority instead of relying on quartz to do it. + (gdk_window_set_type_hint): Use tornoff instead of submenu as the + documentation (and Mitch) suggests. + 2006-08-08 Michael Natterer * gdk/quartz/gdkdrawable-quartz.c: some whitespace and indentation diff --git a/ChangeLog.pre-2-10 b/ChangeLog.pre-2-10 index df068f943b..c994b205c4 100644 --- a/ChangeLog.pre-2-10 +++ b/ChangeLog.pre-2-10 @@ -1,3 +1,18 @@ +2006-08-08 Richard Hult + + * gdk/quartz/GdkQuartzView.c: Just expose the minimal region + instead of the whole rect. + + * gdk/quartz/gdkwindow-quartz.c: + (gdk_window_quartz_process_all_updates), (gdk_window_update_idle), + (gdk_window_impl_quartz_invalidate_maybe_recurse), + (gdk_window_impl_quartz_process_updates), + (_gdk_windowing_window_destroy): Rework the expose handling so that + it works like the X11 backend, using an idle with the right + priority instead of relying on quartz to do it. + (gdk_window_set_type_hint): Use tornoff instead of submenu as the + documentation (and Mitch) suggests. + 2006-08-08 Michael Natterer * gdk/quartz/gdkdrawable-quartz.c: some whitespace and indentation diff --git a/gdk/quartz/GdkQuartzView.c b/gdk/quartz/GdkQuartzView.c index 9fb0a2567f..7cd68ead94 100644 --- a/gdk/quartz/GdkQuartzView.c +++ b/gdk/quartz/GdkQuartzView.c @@ -51,25 +51,42 @@ GdkRectangle gdk_rect; GdkWindowObject *private = GDK_WINDOW_OBJECT (gdk_window); GdkWindowImplQuartz *impl = GDK_WINDOW_IMPL_QUARTZ (private->impl); + const NSRect *drawn_rects; + int count, i; + GdkRegion *region; GDK_QUARTZ_ALLOC_POOL; - gdk_rect.x = rect.origin.x; - gdk_rect.y = rect.origin.y; - gdk_rect.width = rect.size.width; - gdk_rect.height = rect.size.height; - - if (private->event_mask & GDK_EXPOSURE_MASK) + [self getRectsBeingDrawn:&drawn_rects count:&count]; + + region = gdk_region_new (); + + for (i = 0; i < count; i++) + { + gdk_rect.x = drawn_rects[i].origin.x; + gdk_rect.y = drawn_rects[i].origin.y; + gdk_rect.width = drawn_rects[i].size.width; + gdk_rect.height = drawn_rects[i].size.height; + + gdk_region_union_with_rect (region, &gdk_rect); + } + + if (!gdk_region_empty (region) && private->event_mask & GDK_EXPOSURE_MASK) { GdkEvent event; + gdk_rect.x = rect.origin.x; + gdk_rect.y = rect.origin.y; + gdk_rect.width = rect.size.width; + gdk_rect.height = rect.size.height; + event.expose.type = GDK_EXPOSE; event.expose.window = g_object_ref (gdk_window); event.expose.send_event = FALSE; event.expose.count = 0; - event.expose.region = gdk_region_rectangle (&gdk_rect); + event.expose.region = region; event.expose.area = gdk_rect; - + impl->in_paint_rect_count ++; (*_gdk_event_func) (&event, _gdk_event_data); diff --git a/gdk/quartz/gdkwindow-quartz.c b/gdk/quartz/gdkwindow-quartz.c index 4c5e1bed98..7688d67981 100644 --- a/gdk/quartz/gdkwindow-quartz.c +++ b/gdk/quartz/gdkwindow-quartz.c @@ -26,6 +26,10 @@ static gpointer parent_class; +static GSList *update_windows = NULL; +static guint update_idle = 0; + + NSView * gdk_quartz_window_get_nsview (GdkWindow *window) { @@ -241,27 +245,88 @@ gdk_window_impl_quartz_end_paint (GdkPaintable *paintable) } } +static void +gdk_window_quartz_process_all_updates (void) +{ + GSList *old_update_windows = update_windows; + GSList *tmp_list = update_windows; + + update_idle = 0; + update_windows = NULL; + + g_slist_foreach (old_update_windows, (GFunc) g_object_ref, NULL); + + while (tmp_list) + { + GdkWindowObject *private = tmp_list->data; + GdkWindowImplQuartz *impl = (GdkWindowImplQuartz *) private->impl; + int i, n_rects; + GdkRectangle *rects; + + if (private->update_area) + { + gdk_region_get_rectangles (private->update_area, &rects, &n_rects); + + gdk_region_destroy (private->update_area); + private->update_area = NULL; + + for (i = 0; i < n_rects; i++) + { + [impl->view setNeedsDisplayInRect:NSMakeRect (rects[i].x, rects[i].y, + rects[i].width, rects[i].height)]; + } + + [impl->view displayIfNeeded]; + + g_free (rects); + } + + g_object_unref (tmp_list->data); + tmp_list = tmp_list->next; + } + + g_slist_free (old_update_windows); +} + +static gboolean +gdk_window_update_idle (gpointer data) +{ + GDK_THREADS_ENTER (); + gdk_window_quartz_process_all_updates (); + GDK_THREADS_LEAVE (); + + return FALSE; +} + static void gdk_window_impl_quartz_invalidate_maybe_recurse (GdkPaintable *paintable, GdkRegion *region, gboolean (*child_func) (GdkWindow *, gpointer), gpointer user_data) { - GdkWindowImplQuartz *impl = GDK_WINDOW_IMPL_QUARTZ (paintable); - int i, n_rects; - GdkRectangle *rects; + GdkWindowImplQuartz *window_impl = GDK_WINDOW_IMPL_QUARTZ (paintable); + GdkDrawableImplQuartz *drawable_impl = (GdkDrawableImplQuartz *) window_impl; + GdkWindow *window = (GdkWindow *) drawable_impl->wrapper; + GdkWindowObject *private = (GdkWindowObject *) window; + GdkRegion *visible_region; - gdk_region_get_rectangles (region, &rects, &n_rects); + visible_region = gdk_drawable_get_visible_region (window); + gdk_region_intersect (visible_region, region); - for (i = 0; i < n_rects; i++) + if (private->update_area) { - [impl->view setNeedsDisplayInRect:NSMakeRect (rects[i].x, rects[i].y, - rects[i].width, rects[i].height)]; + gdk_region_union (private->update_area, visible_region); + gdk_region_destroy (visible_region); } + else + { + update_windows = g_slist_prepend (update_windows, window); + private->update_area = visible_region; - g_free (rects); - - /* FIXME: Check if we need to traverse the children */ + if (update_idle == 0) + update_idle = g_idle_add_full (GDK_PRIORITY_REDRAW, + gdk_window_update_idle, NULL, NULL); + } } static void @@ -269,10 +334,17 @@ gdk_window_impl_quartz_process_updates (GdkPaintable *paintable, gboolean update_children) { GdkWindowImplQuartz *impl = GDK_WINDOW_IMPL_QUARTZ (paintable); + GdkDrawableImplQuartz *drawable_impl = (GdkDrawableImplQuartz *) impl; + GdkWindowObject *private = (GdkWindowObject *) drawable_impl->wrapper; - [impl->view display]; + if (private->update_area) + { + gdk_region_destroy (private->update_area); + private->update_area = NULL; + } - /* FIXME: Check if display actually updates the children too */ + [impl->view setNeedsDisplay: YES]; + update_windows = g_slist_remove (update_windows, private); } static void @@ -285,7 +357,6 @@ gdk_window_impl_quartz_paintable_init (GdkPaintableIface *iface) iface->process_updates = gdk_window_impl_quartz_process_updates; } - GType _gdk_window_impl_quartz_get_type (void) { @@ -642,7 +713,9 @@ _gdk_windowing_window_destroy (GdkWindow *window, gboolean recursing, gboolean foreign_destroy) { - if (!recursing && ! foreign_destroy) + update_windows = g_slist_remove (update_windows, window); + + if (!recursing && !foreign_destroy) { GdkWindowImplQuartz *impl = GDK_WINDOW_IMPL_QUARTZ (GDK_WINDOW_OBJECT (window)->impl); @@ -655,7 +728,6 @@ _gdk_windowing_window_destroy (GdkWindow *window, [impl->toplevel close]; else if (impl->view) [impl->view release]; - } } @@ -1449,7 +1521,7 @@ gdk_window_set_type_hint (GdkWindow *window, break; case GDK_WINDOW_TYPE_HINT_DROPDOWN_MENU: /* Menu from menubar */ - level = NSSubmenuWindowLevel; + level = NSTornOffMenuWindowLevel; shadow = TRUE; break; -- 2.30.2